package com.sos.service.impl;

import com.sos.model.dto.EmergencyContactAddDTO;
import com.sos.model.dto.EmergencyContactDTO;
import com.sos.model.dto.EmergencyContactUpdateDTO;
import com.sos.model.entity.EmergencyContact;
import com.sos.repository.EmergencyContactRepository;
import com.sos.service.EmergencyContactService;
import com.sos.exception.CustomException;
import com.sos.exception.ErrorCode;
import com.sos.util.UserContextUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 紧急联系人Service实现
 */
@Service
@RequiredArgsConstructor
public class EmergencyContactServiceImpl implements EmergencyContactService {

    private final EmergencyContactRepository contactRepository;
    private final UserContextUtils userContextUtils; // 注入工具类

    /**
     * 新增紧急联系人
     */
    @Override
    public EmergencyContactDTO addContact(EmergencyContactAddDTO addDTO) {

        // 直接调用工具类获取当前用户ID，无需重复编写逻辑
        Long userId = userContextUtils.getCurrentUserId();

        // 2. 转换DTO为实体
        EmergencyContact contact = new EmergencyContact();
        BeanUtils.copyProperties(addDTO, contact);
        contact.setUserId(userId); // 绑定当前用户

        // 3. 保存到数据库
        EmergencyContact savedContact = contactRepository.save(contact);

        // 4. 转换实体为DTO返回
        return convertToDTO(savedContact);
    }

    /**
     * 删除紧急联系人（校验权限：只能删自己的）
     */
    @Override
    public void deleteContact(Long contactId) {
        // 1. 获取当前用户ID
        Long userId = userContextUtils.getCurrentUserId();

        // 2. 检查联系人是否存在且属于当前用户
        EmergencyContact contact = contactRepository.findByIdAndUserId(contactId, userId)
                .orElseThrow(() -> new CustomException(ErrorCode.CONTACT_NOT_FOUND));

        // 3. 删除
        contactRepository.delete(contact);
    }

    /**
     * 修改紧急联系人（校验权限：只能改自己的）
     */
    @Override
    public EmergencyContactDTO updateContact(Long contactId, EmergencyContactUpdateDTO updateDTO) {
        // 1. 获取当前用户ID
        Long userId = userContextUtils.getCurrentUserId();

        // 2. 检查联系人是否存在且属于当前用户
        EmergencyContact contact = contactRepository.findByIdAndUserId(contactId, userId)
                .orElseThrow(() -> new CustomException(ErrorCode.CONTACT_NOT_FOUND));

        // 3. 更新字段（只更新DTO中的非null字段）
        if (updateDTO.getName() != null) contact.setName(updateDTO.getName());
        if (updateDTO.getPhone() != null) contact.setPhone(updateDTO.getPhone());
        if (updateDTO.getRelationship() != null) contact.setRelationship(updateDTO.getRelationship());
        if (updateDTO.getSort() != null) contact.setSort(updateDTO.getSort());

        // 4. 保存更新
        EmergencyContact updatedContact = contactRepository.save(contact);

        // 5. 转换DTO返回
        return convertToDTO(updatedContact);
    }

    /**
     * 查询当前用户的所有紧急联系人
     */
    @Override
    public List<EmergencyContactDTO> getContactList() {
        // 1. 获取当前用户ID
        Long userId = userContextUtils.getCurrentUserId();

        // 2. 查询列表（按sort升序）
        List<EmergencyContact> contactList = contactRepository.findByUserIdOrderBySortAsc(userId);

        // 3. 转换为DTO列表返回
        return contactList.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }

    /**
     * 查询单个紧急联系人（校验权限）
     */
    @Override
    public EmergencyContactDTO getContactById(Long contactId) {
        // 1. 获取当前用户ID
        Long userId = userContextUtils.getCurrentUserId();

        // 2. 检查联系人是否存在且属于当前用户
        EmergencyContact contact = contactRepository.findByIdAndUserId(contactId, userId)
                .orElseThrow(() -> new CustomException(ErrorCode.CONTACT_NOT_FOUND));

        // 3. 转换DTO返回
        return convertToDTO(contact);
    }

    /**
     * 实体转DTO（统一字段映射）
     */
    private EmergencyContactDTO convertToDTO(EmergencyContact contact) {
        EmergencyContactDTO dto = new EmergencyContactDTO();
        BeanUtils.copyProperties(contact, dto);
        return dto;
    }
}